home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d20
/
doorskl3.arc
/
XBBSMSG.ARC
/
GETPUT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-15
|
17KB
|
629 lines
/* primitives for manipulating XBBS message areas
this code hacked out in one sitting by Mark Kimes 06/25/91
compiles; no guarantee that it works. */
/* I'm not quite sure how locking works under DOS-OS/2. Does the seek
to a locked record fail, or the read/write? This code assumes that
either could fail. It locks for all writes, no reads. */
#ifndef __TURBOC__
#define INCL_DOS
#include <os2.h> /* for DosSleep() */
#include <sys/locking.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <fcntl.h>
#include <share.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "xmsg.h"
#ifdef __TURBOC__
#define LK_LOCK 1
#define LK_UNLCK 2
#define DosSleep(x) sleep(1)
/* replacement for MSC's locking() in this module */
int pascal locking (int handle,int type,long length);
#define _fastcall pascal
#endif
/* external variables referenced */
extern char *msgpath;
/* external functions referenced */
/* global variables created here */
int _fastcall get_text (char **hold,XMSG *msg,unsigned int areano,
unsigned int messno) {
/* loads text for XMSG *msg message #messno from areano #areano into
**hold (allocates here, caller must free). Can modify *msg if
message hasn't been previously TREATED. UNLZSSs if message was
compressed. */
int once,reduced = 0,handle;
char *tempo;
char filename[257];
unsigned int temp,len;
long pos;
if(!msg->length) return MSG_NOTEXT;
if(msg->length > 65500U) msg->length = 65500U;
*hold = NULL;
/* open text file */
sprintf(filename,"%sXTEXT.%03x",msgpath,areano);
once = 0;
while ((handle = sopen(filename,O_RDONLY | O_BINARY, SH_DENYNO,S_IREAD | S_IWRITE)) == -1) {
if (errno == EACCES) {
once++;
if (once > 10) {
return MSG_NOACCESS;
}
DosSleep(1000L);
}
else {
return MSG_NOOPEN;
}
}
temp = msg->length;
/* seek to position */
once = 0;
while (lseek(handle,msg->start,SEEK_SET) == -1L) {
if (once < 10) {
once++;
DosSleep(1000L);
}
else {
close(handle);
return MSG_NOSEEK;
}
}
/* load text */
if(msg->length > 65500U) msg->length = 65500U;
ReTry:
*hold = (char *)malloc(msg->length + 1);
if (*hold == NULL) {
if (msg->length > 1024 && !(msg->m_attr & MSGPACKED)) {
msg->length -= 256;
reduced = 1;
goto ReTry;
}
else {
close(handle);
return MSG_NOMEM;
}
}
memset(*hold,0,msg->length);
once = 0;
for(;;) {
pos = tell(handle);
len = (unsigned int)read(handle,*hold,msg->length);
if(!len || len == 65535U) {
once++;
if(once < 10) {
lseek(handle,pos,SEEK_SET);
DosSleep(500L);
}
else {
close(handle);
free(*hold);
*hold = NULL;
return MSG_NOREAD;
}
}
else if(len < (msg->length - 1)) {
reduced = 1;
break;
}
else break;
}
close(handle);
tempo = *hold;
tempo[msg->length - 1] = 0;
tempo[msg->length] = 0;
/* treat text if necessary */
tempo = *hold;
if(!(msg->m_attr & MSGTREATED) &&
/* !(currarea->attr & ANSI) && */ !(msg->m_attr & MSGPACKED)) {
while (*tempo) {
if(*tempo == '\x8d' || *tempo == '\n') {
memmove(tempo,&tempo[1],msg->length - ((unsigned int)tempo -
(unsigned int)*hold));
msg->length--;
if(!msg->length) break;
}
else tempo++;
}
if(*(tempo - 1) != '\r' && tempo > *hold) {
*tempo = '\r';
tempo[1] = 0;
}
/* rewrite treated text */
if(!reduced && temp > ((unsigned int)strlen(*hold) + 1) && **hold) {
msg->length = (unsigned int)strlen(*hold) + 1;
sprintf(filename,"%sXTEXT.%03x",msgpath,areano);
if ((handle = sopen(filename,O_RDWR | O_BINARY, SH_DENYNO,S_IWRITE | S_IREAD)) == -1)
goto OkayThenDont;
once = 0;
while (lseek(handle,msg->start,SEEK_SET) == -1L) {
if (once < 10) {
once++;
DosSleep(100L);
}
else {
close(handle);
goto OkayThenDont;
}
}
if(!locking(handle,LK_LOCK,(long)(msg->length + 1))) {
write(handle,*hold,strlen(*hold));
write(handle,"\0",1);
lseek(handle,msg->start,SEEK_SET);
locking(handle,LK_UNLCK,(long)(msg->length + 1));
close(handle);
/* rewrite header for treated text */
msg->m_attr |= MSGTREATED;
put_mess(msg,areano,messno);
temp = msg->length;
}
}
}
/* UnLZSS compressed text */
if(msg->m_attr & MSGPACKED && !reduced) {
if(unpack_msg(msg,hold) == NULL) { /* extern routine */
if(*hold) free(*hold);
*hold = NULL;
return MSG_NOUNLZSS;
}
}
/* wrapup */
OkayThenDont:
msg->length = temp;
if(reduced) return MSG_REDUCED;
return MSG_NOERR;
}
int _fastcall append_text (XMSG *msg,char *hold,unsigned int areano,
unsigned int messno) {
/* appends text for XMSG *msg, message #messno in area #areano with
text in *hold. updates msg->length and msg->start */
unsigned int messlen = 0;
int handle,once;
long pos;
char filename[257];
if (hold == NULL || !*hold) return MSG_NOTEXT;
/* open text file */
sprintf(filename,"%sXTEXT.%03x",msgpath,areano);
once = 0;
while ((handle = sopen(filename,O_RDWR | O_BINARY | O_CREAT, SH_DENYNO,S_IWRITE | S_IREAD)) == -1) {
if (errno == EACCES) {
if(once < 10) {
DosSleep(1000L);
once++;
}
else {
return MSG_NOACCESS;
}
}
else return MSG_NOOPEN;
}
/* seek to position */
SeekAgain:
once = 0;
while ((pos = lseek(handle,0L,SEEK_END)) == -1L) {
if (once < 10) {
once++;
DosSleep(100L);
}
else {
close(handle);
return MSG_NOSEEK;
}
}
/* lock, write, unlock */
if(!locking(handle,LK_LOCK,65535L)) {
if(lseek(handle,0L,SEEK_END) != pos) {
lseek(handle,pos,SEEK_SET);
locking(handle,LK_UNLCK,65535L);
goto SeekAgain;
}
pos = tell(handle);
messlen += write(handle,hold,sizeof(char) * strlen(hold));
write(handle,"\0",1);
lseek(handle,pos,SEEK_SET);
locking(handle,LK_UNLCK,65535L);
messlen += 2;
msg->length = messlen;
msg->start = pos;
if(msg->length > 65500U) msg->length = 65500U;
close(handle);
return MSG_NOERR;
}
close(handle);
return MSG_NOLOCK;
}
int _fastcall replace_text (XMSG *msg,char *hold,unsigned int areano,
unsigned int messno) {
/* call this to replace text for XMSG *msg, message #messno, areano
#areano with text in *hold. Will append instead of replace if
there's not enough room in existing allocation. Updates msg->length
(and msg->start) */
unsigned int messlen = 0;
int handle,once;
char filename[257];
if (hold == NULL || !*hold) return MSG_NOTEXT;
/* decide whether to append or replace */
if(strlen(hold) > msg->length - 2)
return append_text(msg,hold,areano,messno);
/* open text file */
sprintf(filename,"%sXTEXT.%03x",msgpath,areano);
once = 0;
while ((handle = sopen(filename,O_RDWR | O_BINARY | O_CREAT, SH_DENYNO,S_IWRITE | S_IREAD)) == -1) {
if (errno == EACCES) {
if(once < 10) {
DosSleep(1000L);
once++;
}
else {
return MSG_NOACCESS;
}
}
else return MSG_NOOPEN;
}
/* seek to position */
once = 0;
while (lseek(handle,msg->start,SEEK_SET) == -1L) {
if (once < 10) {
once++;
DosSleep(100L);
}
else {
close(handle);
return MSG_NOSEEK;
}
}
/* lock, write, unlock */
if(!locking(handle,LK_LOCK,65535L)) {
messlen += write(handle,hold,sizeof(char) * strlen(hold));
write(handle,"\0",1);
lseek(handle,msg->start,SEEK_SET);
locking(handle,LK_UNLCK,65535L);
messlen += 2;
msg->length = messlen;
close(handle);
if(msg->length > 65500U) msg->length = 65500U;
return MSG_NOERR;
}
close(handle);
return MSG_NOLOCK;
}
int _fastcall get_mess (XMSG *msg,unsigned int areano,unsigned int messno) {
/* fill XMSG *msg with data for message #messno in area #areano */
int handle,once;
char filename[257];
unsigned int len;
long pos;
/* open data file */
sprintf(filename,"%sXDATA.%03x",msgpath,areano);
if (messno < 1) messno = 1;
once = 0;
while ((handle = sopen(filename,O_RDONLY | O_BINARY, SH_DENYNO,S_IWRITE | S_IREAD)) == -1) {
if (errno == EACCES) {
if(once < 10) {
once++;
DosSleep(1000L);
}
else {
return MSG_NOACCESS;
}
}
else {
return MSG_NOOPEN;
}
}
/* seek to position */
once = 0;
while (lseek(handle,(long)((long)(messno - 1) * (long)sizeof(XMSG)),SEEK_SET) == -1L) {
if(once < 10) {
once++;
DosSleep(100L);
}
else {
close(handle);
return MSG_NOSEEK;
}
}
/* read and wrapup */
once = 0;
memset(msg,0,sizeof(XMSG));
pos = tell(handle);
for(;;) {
len = (unsigned int)read(handle,msg,sizeof(XMSG));
if(!len || len == 65535U) {
once++;
if(once < 10) {
lseek(handle,pos,SEEK_SET);
DosSleep(500L);
}
else {
close(handle);
return MSG_NOREAD;
}
}
else if(len < sizeof(XMSG)) {
close(handle);
return MSG_PARTREAD;
}
else break;
}
close(handle);
return MSG_NOERR;
}
int _fastcall put_mess (USHORT cp,XMSG *msg,unsigned int areano,
unsigned int messno) {
/* write XMSG *msg to message #messno in area #areano */
int handle;
unsigned int x = 0;
char filename[64];
long pos;
/* open data file */
sprintf(filename,"MSG/XDATA.%03x",areano);
while ((handle = sopen(filename,O_NOINHERIT | O_RDWR | O_BINARY | O_CREAT, SH_DENYNO,S_IWRITE | S_IREAD)) == -1) {
if (errno == EACCES) {
x++;
if(x > 9) {
return MSG_NOACCESS;
}
DosSleep(1000L);
}
else {
return MSG_NOOPEN;
}
}
if(messno) {
/* seek to position */
x = 0;
while (lseek(handle,(long)((long)(messno - 1) * (long)sizeof(XMSG)),SEEK_SET) == -1L) {
x++;
if(x > 9) {
close(handle);
return MSG_NOSEEK;
}
}
/* lock, write, unlock */
if(!locking(handle,LK_LOCK,(long)sizeof(XMSG))) {
write(handle,msg,sizeof(XMSG));
lseek(handle,(long)((long)(messno - 1) * (long)sizeof(XMSG)),SEEK_SET);
locking(handle,LK_UNLCK,(long)sizeof(XMSG));
close(handle);
return MSG_NOERR;
}
close(handle);
return MSG_NOLOCK;
}
else { /* append new header */
for(;;) {
x = 0;
while((pos = lseek(handle,0L,SEEK_END)) == -1L) {
x++;
if(x > 9) {
close(handle);
return MSG_NOSEEK;
}
}
if(!locking(handle,LK_LOCK,(long)sizeof(XMSG))) {
if(lseek(handle,0L,SEEK_END) != pos) {
lseek(handle,pos,SEEK_SET);
locking(handle,LK_UNLCK,(long)sizeof(XMSG));
continue;
}
write(handle,msg,sizeof(XMSG));
lseek(handle,pos,SEEK_SET);
locking(handle,LK_UNLCK,(long)sizeof(XMSG));
close(handle);
return MSG_NOERR;
}
close(handle);
return MSG_NOLOCK;
}
}
}
int _fastcall post_message (XMSG *msg,char **hold,unsigned int areano,
int isfile) {
/* post a new message given header, text and area #. if isfile is
non-zero, **hold is name of file containing text to import (note
that hold must be malloced and freeable). text imported from a
file will be treated here; text sent in *hold will not. */
struct stat st;
char filename[257],*tempo;
unsigned int nomess;
int ret;
if(!hold || !*hold || !**hold) return MSG_NOTEXT;
sprintf("%sXDATA.%03x",msgpath,areano);
if(stat(filename,&st)) st.st_size = 0L;
nomess = (unsigned int)(st.st_size / (long)sizeof(XMSG));
if(isfile) { /* load a file for msg text */
strcpy(filename,*hold);
free(*hold);
*hold = NULL;
ret = sopen(filename,O_RDONLY | O_BINARY, SH_DENYNO,S_IWRITE | S_IREAD);
if(ret == -1) return MSG_NOTEXT;
lseek(ret,0L,SEEK_END);
st.st_size = tell(ret);
if(!st.st_size) {
close(ret);
return MSG_NOTEXT;
}
if(st.st_size > 65500L) st.st_size = 65500L;
*hold = (char *)malloc((unsigned int)st.st_size + 1);
if(!*hold) {
close(ret);
return MSG_NOMEM;
}
lseek(ret,0L,SEEK_SET);
if((unsigned int)read(ret,*hold,(unsigned int)st.st_size) !=
(unsigned int)st.st_size) {
close(ret);
free(*hold);
*hold = NULL;
return MSG_NOREAD;
}
close(ret);
tempo = *hold; /* "treat" text */
tempo[(unsigned int)st.st_size] = 0;
msg->length = strlen(tempo);
while (*tempo) {
if(*tempo == '\x8d' || *tempo == '\n') {
memmove(tempo,&tempo[1],msg->length - ((unsigned int)tempo -
(unsigned int)*hold));
msg->length--;
if(!msg->length) {
return MSG_NOTEXT;
}
}
else tempo++;
}
if(*(tempo - 1) != '\r' && tempo > *hold) {
*tempo = '\r';
tempo[1] = 0;
}
}
ret = append_text(msg,*hold,areano,nomess + 1);
if(ret == MSG_NOERR) {
return put_mess(msg,areano,nomess + 1);
}
return ret;
}
#ifdef __TURBOC__
int pascal locking (int handle,int type,long length) {
int x;
if(type == LK_LOCK) {
x = 0;
while(x < 10) {
if(!lock(handle,tell(handle),length)) return 0;
x++;
DosSleep(1000L);
}
}
else if(type == LK_UNLCK) {
return unlock(handle,tell(handle),length);
}
return -1;
}
#endif